// Copyright (c) 2011-2013 The Bitcoin developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "intangiblesdialog.h"
#include "ui_intangiblesdialog.h"

#include "addresstablemodel.h"
#include "ipcoinunits.h"
#include "coincontroldialog.h"
#include "guiutil.h"
#include "optionsmodel.h"
#include "intangiblesentry.h"
#include "walletmodel.h"

#include "base58.h"
#include "coincontrol.h"
#include "ui_interface.h"

///added

#include "key.h"
#include "wallet.h"
#include "useful.h"
#include "uint256.h"
#include "clientversion.h"
#include <boost/lexical_cast.hpp>
#include <boost/algorithm/string/replace.hpp>

#include <QFont>

//added

#include <QMessageBox>
#include <QScrollBar>
#include <QTextDocument>

IntangiblesDialog::IntangiblesDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::IntangiblesDialog),
    model(0)
{
    ui->setupUi(this);
#ifdef Q_OS_MAC // Icons on push buttons are very uncommon on Mac
    //ui->addButton->setIcon(QIcon());
    ui->clearButton->setIcon(QIcon());
    ui->sendButton->setIcon(QIcon());
#endif

	ui->existingTextedit->setFont(GUIUtil::intangibleFont());	

    addEntry();

    connect(ui->clearButton, SIGNAL(clicked()), this, SLOT(clear()));

    
    // Coin Control: clipboard actions
    QAction *clipboardQuantityAction = new QAction(tr("Copy quantity"), this);
    QAction *clipboardAmountAction = new QAction(tr("Copy amount"), this);
    QAction *clipboardFeeAction = new QAction(tr("Copy fee"), this);
    QAction *clipboardAfterFeeAction = new QAction(tr("Copy after fee"), this);
    QAction *clipboardBytesAction = new QAction(tr("Copy bytes"), this);
    QAction *clipboardPriorityAction = new QAction(tr("Copy priority"), this);
    QAction *clipboardLowOutputAction = new QAction(tr("Copy low output"), this);
    QAction *clipboardChangeAction = new QAction(tr("Copy change"), this);
    connect(clipboardQuantityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardQuantity()));
    connect(clipboardAmountAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAmount()));
    connect(clipboardFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardFee()));
    connect(clipboardAfterFeeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardAfterFee()));
    connect(clipboardBytesAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardBytes()));
    connect(clipboardPriorityAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardPriority()));
    connect(clipboardLowOutputAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardLowOutput()));
    connect(clipboardChangeAction, SIGNAL(triggered()), this, SLOT(coinControlClipboardChange()));

    fNewRecipientAllowed = true;
}

void IntangiblesDialog::setModel(WalletModel *model)
{
this->model = model;

    if(model && model->getOptionsModel())
    {
        for(int i = 0; i < ui->entries->count(); ++i)
        {
IntangiblesEntry *entry = qobject_cast<IntangiblesEntry*>(ui->entries->itemAt(i)->widget()); 
            if(entry)
            {
                entry->setModel(model);
            }
        }

        setBalance(model->getBalance(), model->getUnconfirmedBalance(), model->getImmatureBalance());
        connect(model, SIGNAL(balanceChanged(qint64, qint64, qint64)), this, SLOT(setBalance(qint64, qint64, qint64)));
        connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(updateDisplayUnit()));

        // Coin Control
        connect(model->getOptionsModel(), SIGNAL(displayUnitChanged(int)), this, SLOT(coinControlUpdateLabels()));
        connect(model->getOptionsModel(), SIGNAL(coinControlFeaturesChanged(bool)), this, SLOT(coinControlFeatureChanged(bool)));
        connect(model->getOptionsModel(), SIGNAL(transactionFeeChanged(qint64)), this, SLOT(coinControlUpdateLabels()));

    }
}

IntangiblesDialog::~IntangiblesDialog()
{
	delete ui;
}

void IntangiblesDialog::on_checkButton_clicked()
{
	bool valid = false;	
	try {	
	std::string txid, n, hex, redeemScript;	
	std::string tran = ui->existingTextedit->toPlainText().toStdString();
	decodeExchangeableTransaction(tran,txid,n,hex,redeemScript);

///begin kind of unnecessary stuff
	std::string rpc = "getrawtransaction " + txid;
	std::string rpcresult = executeRPCcommand(QString::fromStdString(rpc));	
	rpc = "decoderawtransaction " + rpcresult;
cout << endl << rpc << endl;
	rpcresult = executeRPCcommand(QString::fromStdString(rpc));
	//cout << getRPCvalueVALUE(rpcresult,"value") << endl;
	std::string multi_address = getRPCvalueADDRESS(rpcresult,"address");
	//and again, to get the payer address
	rpc = "getrawtransaction " + getRPCvalueTXID_IN(rpcresult,"txid");
	rpcresult = executeRPCcommand(QString::fromStdString(rpc));	
	rpc = "decoderawtransaction " + rpcresult;
cout << endl << rpc << endl;
	rpcresult = executeRPCcommand(QString::fromStdString(rpc));
cout << "RPC result is: " << endl << rpcresult << endl << "--------------" << endl;
	std::string value = getRPCvalueVALUE_TXIN(rpcresult,"value");
	std::string address_in = getRPCvalueADDRESS_IN(rpcresult,"address");
cout << getRPCvalueADDRESS_IN(rpcresult,"address") << endl;

////all that is kind of unnecessary.
////new stuff
CService addrConnect;
std::string request;
std::string response ("");
addrConnect = CService(IPSELEX_SERVER, 8080, true); 
std::string rest = "/check/"+txid;
request = "GET " + rest + " HTTP/1.1\r\n"
         "Host: " + IPSELEX_SERVER + "\r\n"
         "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
         "Connection: close\r\n"
         "\r\n";
WebRequest(addrConnect, request.c_str(), response);
//strip out the http header, begin at the json
response = response.substr(response.find("{"));

	value = getRPCvalue(response,"amount");
	std::string payeeaddress = getRPCvalue(response,"payeeaddress");
	std::string conditional = getRPCvalue(response,"conditional");

//end new stuffs
		QMessageBox msgBox;
		std::string success = value + " IPC was successfully transferred by " + address_in + " to address " + multi_address + ", via Ipselex. Payee is "+payeeaddress+", conditional on "+conditional;
 		msgBox.setText(QString::fromStdString(success));
		msgBox.setInformativeText("This does not prove that the coins are still held by that address. The coins may have been transferred on if either the payee or Ipselex has validated or cancelled the transaction.");
		msgBox.setStandardButtons(QMessageBox::Ok);
		msgBox.setDefaultButton(QMessageBox::Ok);
		msgBox.exec();

//what the hell is this????
	rpc = "signrawtransaction ";
	rpc = rpc + tran + " '[{\"txid\":\"";
	rpc = rpc + txid + "\", \"vout\":" + n + ", \"scriptPubKey\":\"";
	rpc = rpc + hex + "\", \"redeemScript\":\"";
	rpc = rpc + redeemScript + "\"}]' '[\"";
	std::string rpc_; 
	//payee may not know/remember which address he gave to payer, try them all
	std::string result = executeRPCcommand("listreceivedbyaddress 0 true");
	std::vector<std::string> addresses;
	getRPCvalueADDRESSESfromGROUPING(result, addresses);
	for( vector<std::string>::const_iterator it = addresses.begin(); it != addresses.end(); ++it )
        	{
			try {
			std::string rpc2 = "dumpprivkey " + *it;
			std::string key = executeRPCcommand(QString::fromStdString(rpc2));			
			rpc_ = rpc + key + "\"]'";	
			rpcresult = executeRPCcommand(QString::fromStdString(rpc_));
			if (getRPCvaluebool(rpcresult,"complete")==true)	
				{ valid = true; break; }
			} //end try, to filter out multi addresses
			catch(...) {}
		}
	}
	catch(...)
	{
		QMessageBox msgBox;
 		msgBox.setText("Transaction code is not valid.");
		msgBox.setStandardButtons(QMessageBox::Cancel);
		msgBox.setDefaultButton(QMessageBox::Cancel);
		msgBox.exec();
	}

}

void IntangiblesDialog::on_cancelButton_clicked()
{
	try {	
		QMessageBox msgBoxc;
 		msgBoxc.setText("Are you sure you wish to cancel (refund) the transaction?");
		msgBoxc.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
		msgBoxc.setDefaultButton(QMessageBox::No);
		int ret = msgBoxc.exec();
		if (ret==QMessageBox::No) return;
	std::string txid, n, hex, redeemScript;	
	std::string tran = ui->existingTextedit->toPlainText().toStdString();
	decodeExchangeableTransaction(tran,txid,n,hex,redeemScript);
	std::string rpc = "signrawtransaction ";
	rpc = rpc + tran + " '[{\"txid\":\"";
	rpc = rpc + txid + "\", \"vout\":" + n + ", \"scriptPubKey\":\"";
	rpc = rpc + hex + "\", \"redeemScript\":\"";
	rpc = rpc + redeemScript + "\"}]' '[\"";
	std::string rpc_; std::string rpcresult;
	//payee may not know/remember which address he gave to payer, try them all
	std::string result = executeRPCcommand("listreceivedbyaddress 0 true");
	std::vector<std::string> addresses;
	getRPCvalueADDRESSESfromGROUPING(result, addresses);
	for( vector<std::string>::const_iterator it = addresses.begin(); it != addresses.end(); ++it )
        	{
			try {
			std::string rpc2 = "dumpprivkey " + *it;
			std::string key = executeRPCcommand(QString::fromStdString(rpc2));			
			rpc_ = rpc + key + "\"]'";	
			 rpcresult = executeRPCcommand(QString::fromStdString(rpc_));
			if (getRPCvaluebool(rpcresult,"complete")==true)	
				{ break; }
			} //end try (to filter out multi addresses)
			catch (...) {}
		}
	//and then, send it!

	rpc = "sendrawtransaction " + getRPCvalue(rpcresult,"hex");
	rpcresult = executeRPCcommand(QString::fromStdString(rpc));
		QMessageBox msgBox;
 		msgBox.setText("Transaction cancelled.");
		msgBox.setInformativeText("IPCoins refunded to payer.");
		msgBox.setStandardButtons(QMessageBox::Ok);
		msgBox.setDefaultButton(QMessageBox::Ok);
		msgBox.exec();
	}
	catch(...)
	{
		QMessageBox msgBox;
 		msgBox.setText("Transaction code is not valid, or you do not have permission to cancel the transaction.");
		msgBox.setStandardButtons(QMessageBox::Cancel);
		msgBox.setDefaultButton(QMessageBox::Cancel);
		msgBox.exec();
	}
}

void IntangiblesDialog::on_validateButton_clicked()
{
	try {	
		QMessageBox msgBoxc;
 		msgBoxc.setText("Are you sure you wish to validate (release) the transaction?");
		msgBoxc.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
		msgBoxc.setDefaultButton(QMessageBox::No);
		int ret = msgBoxc.exec();
		if (ret==QMessageBox::No) return;
	std::string txid, n, hex, redeemScript;	
	std::string tran = ui->existingTextedit->toPlainText().toStdString();
	decodeExchangeableTransaction(tran,txid,n,hex,redeemScript);
	std::string rpc = "signrawtransaction ";
	rpc = rpc + tran + " '[{\"txid\":\"";
	rpc = rpc + txid + "\", \"vout\":" + n + ", \"scriptPubKey\":\"";
	rpc = rpc + hex + "\", \"redeemScript\":\"";
	rpc = rpc + redeemScript + "\"}]' '[\"";
	std::string rpc_; std::string rpcresult;
	//payee may not know/remember which address he gave to payer, try them all
	std::string result = executeRPCcommand("listreceivedbyaddress 0 true");
	std::vector<std::string> addresses;
	getRPCvalueADDRESSESfromGROUPING(result, addresses);
	for( vector<std::string>::const_iterator it = addresses.begin(); it != addresses.end(); ++it )
        	{
			try {			
			std::string rpc2 = "dumpprivkey " + *it;
			std::string key = executeRPCcommand(QString::fromStdString(rpc2));			
			rpc_ = rpc + key + "\"]'";	
			rpcresult = executeRPCcommand(QString::fromStdString(rpc_));
			if (getRPCvaluebool(rpcresult,"complete")==true)	
				{ break; }
			} //end try, to filter out multi addresses
			catch (...) {}
		}
	//and then, send it!
	rpc = "sendrawtransaction " + getRPCvalue(rpcresult,"hex");
	rpcresult = executeRPCcommand(QString::fromStdString(rpc));
		QMessageBox msgBox;
 		msgBox.setText("Transaction validated.");
		msgBox.setInformativeText("IPCoins released to payee.");
		msgBox.setStandardButtons(QMessageBox::Ok);
		msgBox.setDefaultButton(QMessageBox::Ok);
		msgBox.exec();
	}
	catch(...)
	{
		QMessageBox msgBox;
 		msgBox.setText("Transaction code is not valid, or you do not have permission to validate the transaction.");
		msgBox.setStandardButtons(QMessageBox::Cancel);
		msgBox.setDefaultButton(QMessageBox::Cancel);
		msgBox.exec();
	}
}

void IntangiblesDialog::on_sendButton_clicked()
{

//TODO: if no internet connection, return

	if(!model || !model->getOptionsModel())
        return;

    QList<SendCoinsRecipient> recipients;
    bool valid = true;
std::string payeePubkey;
std::string conditional;

for(int i = 0; i < ui->entries->count(); ++i)
    {
        IntangiblesEntry *entry = qobject_cast<IntangiblesEntry*>(ui->entries->itemAt(i)->widget());

        if(entry)
        {
                payeePubkey = entry->getPayeepubkey();
        }
    }

for(int i = 0; i < ui->entries->count(); ++i)
    {
        IntangiblesEntry *entry = qobject_cast<IntangiblesEntry*>(ui->entries->itemAt(i)->widget());
        if(entry)
        {
                conditional = entry->getConditional();
        }
    }

    for(int i = 0; i < ui->entries->count(); ++i)
    {
        IntangiblesEntry *entry = qobject_cast<IntangiblesEntry*>(ui->entries->itemAt(i)->widget());
        if(entry)
        {        
		if(entry->validate())
            {
                recipients.append(entry->getValue());
            }
            else
            {
                valid = false;
            }
        }
    }

////////change the recipient here
std::string refund_address = executeRPCcommand("getnewaddress");
std::string new_pubkey = getRPCvalue(executeRPCcommand(QString::fromStdString("validateaddress "+refund_address)), "pubkey");
std::string commandstring = "createmultisig 2 '[\""+(std::string)IPSELEX_PUBKEY+"\",\""+new_pubkey+"\", \""+payeePubkey+"\"]'";
std::string createmultisig = executeRPCcommand(QString::fromStdString(commandstring));
std::string multi_address = getRPCvalue(createmultisig, "address");
std::string redeemScript = getRPCvalue(createmultisig, "redeemScript");
commandstring = "setaccount \""+refund_address+"\" \"ipselex_refund\"";
executeRPCcommand(QString::fromStdString(commandstring));
commandstring = "setaccount \""+multi_address+"\" \"ipselex_onhold\"";
executeRPCcommand(QString::fromStdString(commandstring));
////////grab the ultimate payee address first to xmit to ipselex server
std::string payee_address = recipients.at(0).address.toStdString();
std::string amount = BitcoinUnits::format(model->getOptionsModel()->getDisplayUnit(), recipients.at(0).amount).toStdString();
SendCoinsRecipient* scr = new SendCoinsRecipient(QString::fromStdString(multi_address),"(via Ipselex) "+ recipients.at(0).label, recipients.at(0).amount, recipients.at(0).message);
recipients.clear();
recipients.append(*scr);

if (!recipients.isEmpty())

    if(!valid || recipients.isEmpty())
    {
        return;
    }

    // Format confirmation message
    QStringList formatted;
    foreach(const SendCoinsRecipient &rcp, recipients)
    {
        // generate bold amount string
        QString amount = "<b>" + BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), rcp.amount);
        amount.append("</b>");
        // generate monospace address string
        QString address = "<span style='font-family: monospace;'>" + rcp.address;
        address.append("</span>");

        QString recipientElement;

        if (!rcp.paymentRequest.IsInitialized()) // normal payment
        {
            if(rcp.label.length() > 0) // label with address
            {
                recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.label));
                recipientElement.append(QString(" (%1)").arg(address));
            }
            else // just address
            {
                recipientElement = tr("%1 to %2").arg(amount, address);
            }
        }
        else if(!rcp.authenticatedMerchant.isEmpty()) // secure payment request
        {
            recipientElement = tr("%1 to %2").arg(amount, GUIUtil::HtmlEscape(rcp.authenticatedMerchant));
        }
        else // insecure payment request
        {
            recipientElement = tr("%1 to %2").arg(amount, address);
        }

        formatted.append(recipientElement);
    }

    fNewRecipientAllowed = false;


    WalletModel::UnlockContext ctx(model->requestUnlock());
    if(!ctx.isValid())
    {
        // Unlock wallet was cancelled
        fNewRecipientAllowed = true;
        return;
    }

    // prepare transaction for getting txFee earlier
    WalletModelTransaction currentTransaction(recipients);
    WalletModel::SendCoinsReturn prepareStatus;
    if (model->getOptionsModel()->getCoinControlFeatures()) // coin control enabled
        prepareStatus = model->prepareTransaction(currentTransaction, CoinControlDialog::coinControl);
    else
        prepareStatus = model->prepareTransaction(currentTransaction);

    // process prepareStatus and on error generate message shown to user
    processSendCoinsReturn(prepareStatus,
        BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), currentTransaction.getTransactionFee()));

    if(prepareStatus.status != WalletModel::OK) {
        fNewRecipientAllowed = true;
        return;
    }

    qint64 txFee = currentTransaction.getTransactionFee();
    QString questionString = tr("Are you sure you want to transact?");
    questionString.append("<br /><br />%1");

    if(txFee > 0)
    {
        // append fee string if a fee is required
        questionString.append("<hr /><span style='color:#aa0000;'>");
        questionString.append(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), txFee));
        questionString.append("</span> ");
        questionString.append(tr("added as transaction fee"));
    }

    // add total amount in all subdivision units
    questionString.append("<hr />");
    qint64 totalAmount = currentTransaction.getTotalTransactionAmount() + txFee;
    QStringList alternativeUnits;
    foreach(BitcoinUnits::Unit u, BitcoinUnits::availableUnits())
    {
        if(u != model->getOptionsModel()->getDisplayUnit())
            alternativeUnits.append(BitcoinUnits::formatWithUnit(u, totalAmount));
    }
    questionString.append(tr("Total Amount %1 (= %2)")
        .arg(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), totalAmount))
        .arg(alternativeUnits.join(" " + tr("or") + " ")));

    QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm send coins"),
        questionString.arg(formatted.join("<br />")),
        QMessageBox::Yes | QMessageBox::Cancel,
        QMessageBox::Cancel);

    if(retval != QMessageBox::Yes)
    {
        fNewRecipientAllowed = true;
        return;
    }

    // now send the prepared transaction
    WalletModel::SendCoinsReturn sendStatus = model->sendCoins(currentTransaction);
    // process sendStatus and on error generate message shown to user
    processSendCoinsReturn(sendStatus);

    if (sendStatus.status == WalletModel::OK)
    {
        accept();
        CoinControlDialog::coinControl->UnSelectAll();
	std::string transaction = executeRPCcommand("listtransactions \"\" 1");
	transaction = transaction.substr(1,strlen(transaction.c_str())-2);
	std::string txid = getRPCvalue(transaction,"txid");
	std::string rawtransaction = executeRPCcommand(QString::fromStdString("getrawtransaction " + txid));
	std::string decoderawtransaction = executeRPCcommand(QString::fromStdString("decoderawtransaction " + rawtransaction));
	cout << decoderawtransaction << endl;
	std::string hex = getRPCvalueHEX(decoderawtransaction,"hex");
	std::string n = getRPCvalueN(decoderawtransaction,"n");
	std::string contract = " '[{\"txid\":\""+txid+"\",\"vout\":"+n+",\"scriptPubKey\":\""+hex+"\",\"redeemScript\":\""+redeemScript+"\"}]' ";
	std::string addr_amount = "'{\""+payee_address+"\":"+amount+"}'";
	std::string contracttransaction = executeRPCcommand(QString::fromStdString("createrawtransaction"+contract+addr_amount));
	std::string privkey = executeRPCcommand(QString::fromStdString("dumpprivkey "+refund_address));
	cout << "Part: -------------------" << endl;
	cout << "signrawtransaction " + contracttransaction+" "+contract+"'[\""+privkey+"\"]'" << endl;
	std::string partsignedtransaction = executeRPCcommand(QString::fromStdString("signrawtransaction "+contracttransaction+" "+contract+"'[\""+privkey+"\"]'"));
partsignedtransaction = getRPCvalue(partsignedtransaction, "hex");
	//now create the refund transaction
	addr_amount = "'{\""+refund_address+"\":"+amount+"}'";
std::string refundtransaction = executeRPCcommand(QString::fromStdString("createrawtransaction"+contract+addr_amount));
cout << "Part (refund): -------------------" << endl;
	cout << "signrawtransaction " + contracttransaction+" "+contract+"'[\""+privkey+"\"]'" << endl;
	std::string partsignedrefundtransaction = executeRPCcommand(QString::fromStdString("signrawtransaction "+refundtransaction+" "+contract+"'[\""+privkey+"\"]'"));
	partsignedrefundtransaction = getRPCvalue(partsignedrefundtransaction, "hex");

cout << "Pay_on transaction: ----------------------" << endl;
cout << partsignedtransaction << endl;
cout << "Refund transaction: ----------------------" << endl;
cout << partsignedrefundtransaction << endl;
	///end create & send refund transaction
	///Now, pass both to the server to check the conditional and if/when it becomes
	///true, sign and broadcast the pay_on transaction, or if false, the refund
CService addrConnect;
std::string request;
std::string response ("");
addrConnect = CService(IPSELEX_SERVER, 8080, true); 
std::string rest = "/store/"+boost::lexical_cast<string>(CLIENT_VERSION)+"/"+partsignedtransaction+"/"+partsignedrefundtransaction+"/"+txid+"/"+n+"/"+hex+"/"+redeemScript+"/"+refund_address+"/"+payee_address+"/"+payeePubkey+"/"+amount+"/"+GUIUtil::HtmlEscape(QString::fromStdString(boost::replace_all_copy(conditional, " ", "_"))).toStdString();
request = "GET " + rest + " HTTP/1.1\r\n"
         "Host: " + IPSELEX_SERVER + "\r\n"
         "User-Agent: Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)\r\n"
         "Connection: close\r\n"
         "\r\n";
WebRequest(addrConnect, request.c_str(), response);
//strip out the http header, begin at the json
response = response.substr(response.find("{"));
if (response!="")
{
	std::string cmd = getRPCvalue(response,"cmd");
	std::string msg = getRPCvalue(response,"msg");
	if (cmd=="msgbox_ok")
	{
		QMessageBox msgBox;
 		msgBox.setText(QString::fromStdString("Success. If conditional becomes true, " + amount + " IPC will be transferred to " + payee_address + ". If conditional becomes false, it will be returned to your address " + refund_address + ".\nPayee can activate refund or on payment at any time using the codes given in the box."));
 		msgBox.setInformativeText(QString::fromStdString(msg));
		msgBox.setStandardButtons(QMessageBox::Ok);
		msgBox.exec();
	}
	if (cmd=="msgbox_error")
	{
		QMessageBox msgBox;
 		msgBox.setText(QString::fromStdString(msg));
 		msgBox.setInformativeText("Please try again later.");
		msgBox.setStandardButtons(QMessageBox::Cancel);
		msgBox.exec();
	}
	std::string display ("");
	display = "You may wish to give this code to payee, so they can refund you:\n\n";
	display = display + buildExchangeableTransaction(partsignedrefundtransaction, txid, n, hex, redeemScript) + "\n\n";
	display = display + "If at any time you want payee to receive their IPCoins, without waiting for Ipselex to confirm the conditional, give them this code:\n\n";
	display = display + buildExchangeableTransaction(partsignedtransaction, txid, n, hex, redeemScript);
	
	ui->existingTextedit->setText(QString::fromStdString(display));

}
	///end webrequest
    }
    fNewRecipientAllowed = true;
}

void IntangiblesDialog::clear()
{
    // Remove entries until only one left
    while(ui->entries->count())
    {
        ui->entries->takeAt(0)->widget()->deleteLater();
    }
    addEntry();
    updateTabsAndLabels();
}

void IntangiblesDialog::reject()
{
    clear();
}

void IntangiblesDialog::accept()
{
    //clear();
}

IntangiblesEntry *IntangiblesDialog::addEntry()
{  
	IntangiblesEntry *entry = new IntangiblesEntry(this);
    entry->setModel(model);
    ui->entries->insertWidget(0,entry);
    connect(entry, SIGNAL(removeEntry(IntangiblesEntry*)), this, SLOT(removeEntry(IntangiblesEntry*)));
    connect(entry, SIGNAL(payAmountChanged()), this, SLOT(coinControlUpdateLabels()));

    updateTabsAndLabels();

    // Focus the field, so that entry can start immediately
    entry->clear();
    entry->setFocus();
    ui->scrollAreaWidgetContents->resize(ui->scrollAreaWidgetContents->sizeHint());
    qApp->processEvents();
    QScrollBar* bar = ui->scrollArea->verticalScrollBar();
    if(bar)
        bar->setSliderPosition(bar->maximum());
    return entry;
}

void IntangiblesDialog::updateTabsAndLabels()
{
    setupTabChain(0);
}

void IntangiblesDialog::removeEntry(IntangiblesEntry* entry)
{
    entry->hide();
    // If the last entry is about to be removed add an empty one
    if (ui->entries->count() == 1)
        addEntry();

    entry->deleteLater();

    updateTabsAndLabels();
}

QWidget *IntangiblesDialog::setupTabChain(QWidget *prev)
{
    for(int i = 0; i < ui->entries->count(); ++i)
    {
        IntangiblesEntry *entry = qobject_cast<IntangiblesEntry*>(ui->entries->itemAt(i)->widget());
        if(entry)
        {
            prev = entry->setupTabChain(prev);
        }
    }
    return ui->sendButton;
}

void IntangiblesDialog::setAddress(const QString &address)
{
    IntangiblesEntry *entry = 0;
    // Replace the first entry if it is still unused
    if(ui->entries->count() == 1)
    {
        IntangiblesEntry *first = qobject_cast<IntangiblesEntry*>(ui->entries->itemAt(0)->widget());
        if(first->isClear())
        {
            entry = first;
        }
    }
    if(!entry)
    {
        entry = addEntry();
    }

    entry->setAddress(address);
}

void IntangiblesDialog::pasteEntry(const SendCoinsRecipient &rv)
{
    if(!fNewRecipientAllowed)
        return;

    IntangiblesEntry *entry = 0;
    // Replace the first entry if it is still unused
    if(ui->entries->count() == 1)
    {
        IntangiblesEntry *first = qobject_cast<IntangiblesEntry*>(ui->entries->itemAt(0)->widget());
        if(first->isClear())
        {
            entry = first;
        }
    }
    if(!entry)
    {
        entry = addEntry();
    }

    entry->setValue(rv);
    updateTabsAndLabels();
}

bool IntangiblesDialog::handlePaymentRequest(const SendCoinsRecipient &rv)
{
    QString strSendCoins = tr("Send Coins");
    if (rv.paymentRequest.IsInitialized()) {
        // Expired payment request?
        const payments::PaymentDetails& details = rv.paymentRequest.getDetails();
        if (details.has_expires() && (int64_t)details.expires() < GetTime())
        {
            emit message(strSendCoins, tr("Payment request expired"),
                CClientUIInterface::MSG_WARNING);
            return false;
        }
    }
    else {
        CBitcoinAddress address(rv.address.toStdString());
        if (!address.IsValid()) {
            emit message(strSendCoins, tr("Invalid payment address %1").arg(rv.address),
                CClientUIInterface::MSG_WARNING);
            return false;
        }
    }

    pasteEntry(rv);
    return true;
}

void IntangiblesDialog::setBalance(qint64 balance, qint64 unconfirmedBalance, qint64 immatureBalance)
{
    Q_UNUSED(unconfirmedBalance);
    Q_UNUSED(immatureBalance);

    if(model && model->getOptionsModel())
    {
        ui->labelBalance->setText(BitcoinUnits::formatWithUnit(model->getOptionsModel()->getDisplayUnit(), balance));
    }
}

void IntangiblesDialog::updateDisplayUnit()
{
    setBalance(model->getBalance(), 0, 0);
}

void IntangiblesDialog::processSendCoinsReturn(const WalletModel::SendCoinsReturn &sendCoinsReturn, const QString &msgArg)
{
    QPair<QString, CClientUIInterface::MessageBoxFlags> msgParams;
    // Default to a warning message, override if error message is needed
    msgParams.second = CClientUIInterface::MSG_WARNING;

    // This comment is specific to SendCoinsDialog usage of WalletModel::SendCoinsReturn.
    // WalletModel::TransactionCommitFailed is used only in WalletModel::sendCoins()
    // all others are used only in WalletModel::prepareTransaction()
    switch(sendCoinsReturn.status)
    {
    case WalletModel::InvalidAddress:
        msgParams.first = tr("The recipient address is not valid, please recheck.");
        break;
    case WalletModel::InvalidAmount:
        msgParams.first = tr("The amount to pay must be larger than 0.");
        break;
    case WalletModel::AmountExceedsBalance:
        msgParams.first = tr("The amount exceeds your balance.");
        break;
    case WalletModel::AmountWithFeeExceedsBalance:
        msgParams.first = tr("The total exceeds your balance when the %1 transaction fee is included.").arg(msgArg);
        break;
    case WalletModel::DuplicateAddress:
        msgParams.first = tr("Duplicate address found, can only send to each address once per send operation.");
        break;
    case WalletModel::TransactionCreationFailed:
        msgParams.first = tr("Transaction creation failed!");
        msgParams.second = CClientUIInterface::MSG_ERROR;
        break;
    case WalletModel::TransactionCommitFailed:
        msgParams.first = tr("The transaction was rejected! This might happen if some of the coins in your wallet were already spent, such as if you used a copy of wallet.dat and coins were spent in the copy but not marked as spent here.");
        msgParams.second = CClientUIInterface::MSG_ERROR;
        break;
    // included to prevent a compiler warning.
    case WalletModel::OK:
    default:
        return;
    }

    emit message(tr("Send Coins"), msgParams.first, msgParams.second);
}

